import pygame
import time
from random import randint
from sys import exit
from pygame.locals import *

# 坦克大战主窗口
class TankMain():
    width = 800
    height = 530

    # 敌方坦克
    enemyTankList = pygame.sprite.Group()
    # 我方坦克
    myTank = None

    # 我方子弹
    myMissiles = pygame.sprite.Group()
    #敌方子弹
    enemyMissiles = pygame.sprite.Group()

    #爆炸
    explodes = []

    # 墙
    walls = pygame.sprite.Group()

    # 启动游戏
    def startGame(self):
        pygame.init()
        # 设置主窗口大小
        screen = pygame.display.set_mode((TankMain.width,TankMain.height),0,32)

        pygame.display.set_caption("天天的坦克大战")

        #我方坦克
        TankMain.myTank = MyTank(screen)

        for i in range(1,5):
            wall = Wall(screen,(TankMain.width-5*Wall.width)/2+i*Wall.width,TankMain.height-200)
            TankMain.walls.add(wall)

        while True:

            # 获取事件
            self.get_event(TankMain.myTank)

            # 设置背景颜色
            screen.fill((0, 0, 0))

            for wall in TankMain.walls:
                wall.display()
                wall.hitOther()

            #设置文字
            for i,text in enumerate(self.write_font(),1) :
                screen.blit(text,(5,15*i))

            if len(TankMain.enemyTankList) == 0:
                for i in range(0, 5):
                    TankMain.enemyTankList.add(EnemyTank(screen))

            if TankMain.myTank.live:
                # 显示坦克
                TankMain.myTank.display()
                TankMain.myTank.move()
                TankMain.myTank.beHit()
            else:
                # 复活
                TankMain.myTank = MyTank(screen)

            #显示敌方坦克
            for enemyTank in TankMain.enemyTankList:
                enemyTank.display()
                enemyTank.randomMove()
                enemyMissile = enemyTank.randomFire()
                if enemyMissile:
                    TankMain.enemyMissiles.add(enemyMissile)

            #显示我方炮弹
            for missile in TankMain.myMissiles:
                if missile.live:
                    missile.display()
                    missile.move()
                    missile.hit_tank()
                else:
                    TankMain.myMissiles.remove(missile)

            # 显示敌方炮弹
            for missile in TankMain.enemyMissiles:
                if missile.live:
                    missile.display()
                    missile.move()
                    # missile.hit_tank()
                else:
                    TankMain.enemyMissiles.remove(missile)

            #显示爆炸效果
            for explode in TankMain.explodes:
                explode.display()

            pygame.display.update()
            time.sleep(0.05)


    #关闭游戏
    def stopGame(self):
        exit()

    #设置显示的文字
    def write_font(self):
        font = pygame.font.SysFont("SimHei",14)
        text1 = font.render("敌方坦克数量：%d"%len(TankMain.enemyTankList),True,(255,150,0))
        text2 = font.render("我方子弹数量：%d" % len(TankMain.myMissiles), True, (255, 50, 0))
        return text1,text2

    #监听事件
    def get_event(self,myTank):

        for e in pygame.event.get():
            if e.type == QUIT:
                self.stopGame()
            if e.type == KEYDOWN and myTank.live: #改变移动方向
                if e.key == K_UP:
                    myTank.direction = "U"
                    myTank.stop = False
                if e.key == K_DOWN:
                    myTank.direction = "D"
                    myTank.stop = False
                if e.key == K_LEFT:
                    myTank.direction = "L"
                    myTank.stop = False
                if e.key == K_RIGHT:
                    myTank.direction = "R"
                    myTank.stop = False
                if e.key == K_SPACE:
                    TankMain.myMissiles.add(myTank.fire())
            elif e.type == KEYDOWN and not myTank.live:
                if e.key == K_n:
                    TankMain.myTank = MyTank(myTank.screen)
                    # TankMain.myTank.live = True
            if e.type == KEYUP:
                if e.key == K_UP or e.key == K_DOWN or e.key == K_RIGHT or e.key == K_LEFT:
                    myTank.stop = True



#所有类的基类
class BaseItem(pygame.sprite.Sprite):

    #设置成员变量
    def __init__(self,screen):
        pygame.sprite.Sprite.__init__(self)
        self.screen = screen
        self.live = True

    #显示对象
    def display(self):
        if self.live:
            self.image = self.images[self.direction]
            self.screen.blit(self.image, self.rect)

# 坦克类
class Tank(BaseItem):
    width = 60
    height = 60
    #初始化坦克
    def __init__(self,screen):
        super().__init__(screen)
        self.direction = "U"
        self.speed = 5


    #坦克移动
    def move(self):
        if not self.stop:
            self.oldLeft = self.rect.left
            self.oldTop = self.rect.top
            if self.direction == "L":
                if self.rect.left>0:
                    self.rect.left -= self.speed
                else:
                    self.rect.left = 0
            if self.direction == "R":
                if self.rect.right < TankMain.width:
                    self.rect.right += self.speed
                else:
                    self.rect.right = TankMain.width
            if self.direction == "U":
                if self.rect.top>0:
                    self.rect.top -= self.speed
                else:
                    self.rect.top = 0
            if self.direction == "D":
                if self.rect.bottom < TankMain.height:
                    self.rect.bottom += self.speed
                else:
                    self.rect.bottom = TankMain.height

    def fire(self):
        missile = Missile(self)
        return missile

    # 待在原来的地方不动，避免撞墙上，被墙粘住
    def stay(self):
        self.rect.left = self.oldLeft
        self.rect.top = self.oldTop

#我方坦克
class MyTank(Tank):
    def __init__(self,screen):
        super().__init__(screen)
        self.stop = True
        self.images = {}
        self.images["U"] = pygame.image.load("images/p1tankU.gif")
        self.images["D"] = pygame.image.load("images/p1tankD.gif")
        self.images["L"] = pygame.image.load("images/p1tankL.gif")
        self.images["R"] = pygame.image.load("images/p1tankR.gif")
        self.image = self.images[self.direction]

        self.rect = self.image.get_rect()
        self.rect.left = TankMain.width/2
        self.rect.top = TankMain.height -100

        self.oldLeft = self.rect.left
        self.oldTop = self.rect.top

    def fire(self):
        missile = MyMissile(self)
        return missile

    # 被击中
    def beHit(self):
        missileList = pygame.sprite.spritecollide(self,TankMain.enemyMissiles,False)
        for missle in missileList:
            #产生爆炸
            e = Explode(self.screen,self.rect)
            TankMain.explodes.append(e)
            #删除子弹和坦克
            self.live = False
            missle.live = False
            # self = None
            TankMain.enemyMissiles.remove(missle)

#敌方坦克
class EnemyTank(Tank):
    def __init__(self,screen):
        super().__init__(screen)
        self.step = 20
        self.speed = 4
        self.stop = True
        self.images = {}
        self.images["U"] = pygame.image.load("images/enemy1U.gif")
        self.images["D"] = pygame.image.load("images/enemy1D.gif")
        self.images["L"] = pygame.image.load("images/enemy1L.gif")
        self.images["R"] = pygame.image.load("images/enemy1R.gif")
        self.image = self.images[self.direction]
        self.rect = self.image.get_rect()
        # self.rect.left = randint(1,5)*(TankMain.width/(5-1))
        self.rect.left = randint(1,TankMain.width)
        self.rect.top = 100

        self.oldLeft = self.rect.left
        self.oldTop = self.rect.top

    #随机获取一个方向
    def getRandomDirection(self):
        d = randint(0,4)
        if d == 0:
            self.stop = True
        elif d == 1:
            self.direction = "U"
            self.stop = False
        elif d == 2:
            self.direction = "R"
            self.stop = False
        elif d == 3:
            self.direction = "D"
            self.stop = False
        elif d == 4:
            self.direction = "L"
            self.stop = False

    #随机开始移动,控制每隔几步变化一次方向
    def randomMove(self):

        if self.step == 0:
            self.getRandomDirection()
            self.step = 20
        else:
            self.step -= 1

        self.move()

    #随机开火
    def randomFire(self):
        r = randint(1,100)
        missile = None
        if r == 10:
            missile = EnemyMissile(self)
        return missile

#子弹
class Missile(BaseItem):
    width = 17
    height = 17
    def __init__(self,tank):
        super().__init__(tank.screen)
        self.direction = tank.direction

        self.speed = 12
        self.good = False #True 是我方炮弹 False 是敌方炮弹
        self.images = {}
        self.images["U"] = pygame.image.load("images/tankmissile.gif")
        self.images["D"] = pygame.image.load("images/tankmissile.gif")
        self.images["L"] = pygame.image.load("images/tankmissile.gif")
        self.images["R"] = pygame.image.load("images/tankmissile.gif")
        self.image = self.images[self.direction]

        self.rect = self.image.get_rect()
        self.rect.left = tank.rect.left+(tank.width-Missile.width)/2
        self.rect.top = tank.rect.top + (tank.height-Missile.height)/2

    #子弹移动
    def move(self):
        if self.live:
            if self.direction == "L":
                if self.rect.left>0:
                    self.rect.left -= self.speed
                else:
                    self.live = False
            if self.direction == "R":
                if self.rect.right < TankMain.width:
                    self.rect.right += self.speed
                else:
                    self.live = False
            if self.direction == "U":
                if self.rect.top>0:
                    self.rect.top -= self.speed
                else:
                    self.live = False
            if self.direction == "D":
                if self.rect.bottom < TankMain.height:
                    self.rect.bottom += self.speed
                else:
                    self.live = False

    #击中坦克
    def hit_tank(self):
        hitTankList = pygame.sprite.spritecollide(self,TankMain.enemyTankList,False)
        for tank in hitTankList:
            #产生爆炸
            e = Explode(self.screen,tank.rect)
            TankMain.explodes.append(e)
            #删除子弹和敌方坦克
            self.live = False
            Tank.live = False
            if self in TankMain.myMissiles:
                TankMain.myMissiles.remove(self)
            TankMain.enemyTankList.remove(tank)


#我方子弹
class MyMissile(Missile):
    def __init__(self,tank):
        super().__init__(tank)

#敌方子弹
class EnemyMissile(Missile):
    def __init__(self,tank):
        super().__init__(tank)

#爆炸类
class Explode(BaseItem):
    def __init__(self,screen,rect):
        super().__init__(screen)
        self.rect = rect
        self.images = [pygame.image.load("images/blast1.gif"),\
                       pygame.image.load("images/blast2.gif"),\
                       pygame.image.load("images/blast3.gif"),\
                       pygame.image.load("images/blast4.gif"),\
                       pygame.image.load("images/blast5.gif"),\
                       pygame.image.load("images/blast6.gif"),\
                       pygame.image.load("images/blast7.gif"),\
                       pygame.image.load("images/blast8.gif")]
        self.step = 1

    #显示对象
    def display(self):
        if self.live:
            if self.step<8:
                self.screen.blit(self.images[self.step], self.rect)
                self.step+=1
            else:
                self.live = False

            # self.image = self.images[self.step]
            # self.screen.blit(self.image, self.rect)

#墙
class Wall(BaseItem):
    width = 60
    height = 60
    def __init__(self,screen,left,top):
        super().__init__(screen)
        self.image = pygame.image.load("images/steels.gif")
        self.rect = self.image.get_rect()
        self.rect.left = left
        self.rect.top = top

    #展示墙
    def display(self):
        self.screen.blit(self.image,self.rect)

    # 撞墙
    def hitOther(self):
        #判断我方坦克是否撞到墙
        flag = pygame.sprite.collide_rect(self,TankMain.myTank)
        if flag:
            TankMain.myTank.stay()
        #判断敌方坦克是否撞到墙
        if len(TankMain.enemyTankList)>0:
            tankList = pygame.sprite.spritecollide(self,TankMain.enemyTankList,False)
            for tank in tankList:
                tank.stay()
        #判断敌方子弹是否碰到墙
        if TankMain.enemyMissiles:
            missileList = pygame.sprite.spritecollide(self, TankMain.enemyMissiles, False)
            for missile in missileList:
                TankMain.enemyMissiles.remove(missile)
        #判断我方子弹是否碰到墙
        if TankMain.myMissiles:
            missileList = pygame.sprite.spritecollide(self, TankMain.myMissiles, False)
            for missile in missileList:
                TankMain.myMissiles.remove(missile)

game = TankMain()
game.startGame()